import {
    Node,
    Label,
    UITransform,
    director,
    view,
    instantiate,
    resources,
    Font,
    sys,
    Canvas,
    Vec2,
    v2,
    Layers,
} from 'cc';

export class TextLog {
    private static _instance: TextLog;
    private _textMap = new Map<string, string>();
    private _displayNode: Node;
    private _labelNodes: Map<string, Node> = new Map();

    private constructor() {
        this._displayNode = new Node('TextLogDisplay');
        this._displayNode.layer = Layers.BitMask.UI_2D;
        const uiTransform = this._displayNode.addComponent(UITransform);
        uiTransform.setAnchorPoint(0, 1); // 左上角
        this._displayNode.setPosition(
            -view.getVisibleSize().width / 2 + 20,
            view.getVisibleSize().height / 2 - 20,
        );
        const canvas = director.getScene()?.getComponentInChildren(Canvas);
        if (canvas) {
            canvas.node.addChild(this._displayNode);
        }
        // director.getScene()?.addChild(this._displayNode);
    }

    public static get instance(): TextLog {
        if (!this._instance) {
            this._instance = new TextLog();
        }
        return this._instance;
    }

    public log(key: string, value: string) {
        this._textMap.set(key, value);

        let labelNode = this._labelNodes.get(key);
        if (!labelNode) {
            labelNode = new Node(`label_${key}`);
            labelNode.addComponent(UITransform).anchorPoint = v2(0, 1);
            labelNode.layer = Layers.BitMask.UI_2D;
            const label = labelNode.addComponent(Label);
            label.string = `${key}: ${value}`;
            label.fontSize = 20;
            label.lineHeight = 24;
            label.color.set(255, 255, 255, 255);

            label.enableOutline = true;
            label.outlineColor.set(0, 0, 0, 255);
            label.outlineWidth = 2;

            this._displayNode.addChild(labelNode);
            this._labelNodes.set(key, labelNode);
        } else {
            const label = labelNode.getComponent(Label);
            if (label) label.string = `${key}: ${value}`;
        }

        this._updateLayout();
    }

    public clear() {
        this._textMap.clear();
        for (const node of this._labelNodes.values()) {
            node.removeFromParent();
        }
        this._labelNodes.clear();
    }

    private _updateLayout() {
        let yOffset = 0;
        for (const node of this._labelNodes.values()) {
            node.setPosition(0, -yOffset);
            yOffset += 24;
        }
    }
}

function setAnchorPoint(node: Node, v: Vec2) {
    let trans = node.getComponent(UITransform);
    if (!trans) {
        trans.addComponent(UITransform);
    }
    trans.setAnchorPoint(v);
}

function setLayer(node: Node, layer: string) {
    node.layer = Layers.BitMask.UI_2D;
}
